home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / rs0422.zip / CONFIGUR / MHEARD.C < prev    next >
C/C++ Source or Header  |  1990-10-14  |  11KB  |  406 lines

  1. /*
  2.  * Copyright 1988 by the Radio Amateur Telecommunications Society
  3.  * and Thomas A. Moulton, W2VY
  4.  *
  5.  * This software may only be modified, copied, distributed or
  6.  * executed for non-profit purposes by individuals operating
  7.  * systems in the Amateur Radio Service.  Credit to the
  8.  * author(s) and to the Radio Amateur Telecommunications Society
  9.  * must be made in modules where RATS provided software is used,
  10.  * and in any announcements and documentation.  
  11.  *
  12.  * As a non-profit, research and development organization,  the
  13.  * Radio Amateur Telecommunications Society distributes software
  14.  * in both executable and source forms.  This policy is in place
  15.  * to encourage the development and distribution of OSI-based,
  16.  * networking tools.  In order to protect the interests of the
  17.  * Society and the authors, we have placed some conditions
  18.  * of use on the software.  Other groups are encouraged
  19.  * to place the same or similar guidelines on
  20.  * software they produce.
  21.  *
  22.  * The Radio Amateur Telecommunications Society reserves the right
  23.  * to specify and alter the terms under which software provided by
  24.  * the Society may be used.  This policy is consistent with the 
  25.  * objective of uniform and consistent "Open Systems Interconnections."
  26.  * 
  27.  * All acceptable Amateur Radio related uses of this software
  28.  * will be outlined in the "ROSE Implementer's Guide".  Individuals
  29.  * or organizations wishing to add to, or modify the provisions of
  30.  * the guide to accommodate local or evolutionary requirements
  31.  * should document the proposed change(s) and forward them to the
  32.  * Society.  If accepted, written notification will be provided by
  33.  * the Society to the submitting organization or individual(s).
  34.  * The Society will then issue a "ROSE Implementer's Guide Change
  35.  * Notice".  Periodically, the Society will re-issue the "ROSE 
  36.  * Implementer's Guide" and incorporate the text of the change 
  37.  * notices.  This procedure has been put in to place to ensure
  38.  * compatibility between systems and to ensure their "Openness"
  39.  * and interoperability.
  40.  *
  41.  * No part of this software may be used in other packages 
  42.  * without prior authorization from the author or the Society.  
  43.  * Software incorporating this module, all or in part, must be 
  44.  * provided to the Society prior to distribution or use by
  45.  * anyone not directly involved in testing of the revised  
  46.  * environment.  Current releases of the combined software must
  47.  * be provided to the Society in both source and executable
  48.  * forms.  Adequate documention to produce an executable module 
  49.  * from the provided source must also be included.
  50.  *
  51.  * Non-Amateur Radio non-profit uses may be authorized on a case
  52.  * by case basis.  Inquiries for such use may be made in writing
  53.  * to the Society. Non-commercial uses consistent with the
  54.  * general principles of Open Systems Interconnection Reference
  55.  * Model will be generally considered with favor.
  56.  *
  57.  * Commercial licensing of the software is also available based
  58.  * on normal commercial terms.  Licensing inquiries should be
  59.  * directed to the Society.  Commercial licensing of the standard
  60.  * software will be done in situations which materially benefit
  61.  * the Amateur Radio Packet Network.  Additional licensing is
  62.  * reserved by the individual authors.
  63.  * 
  64.  * The Radio Amateur Telecommunications Society provides this software
  65.  * on an "as is" basis.  The Society assumes no liability for
  66.  * loss incurred through the use of this software.  Amateur Radio
  67.  * use of this software implies non-commercial and voluntary 
  68.  * development, deployment and use of this software in a "Amateur",
  69.  * non-commercial service.  Commercial users are encouraged to
  70.  * inspect their copies of the source code.  Source code modification
  71.  * licenses are available if a combined Object and Source Code
  72.  * license was not originally established.
  73.  * 
  74.  * The Society may be contacted by writing or calling at:
  75.  * 
  76.  * The Radio Amateur Telecommunications Society 
  77.  * 206 North Vivyen Street.
  78.  * Bergenfield, New Jersey 07621
  79.  *
  80.  * Telephone: 201-387-8896
  81.  *
  82.  */
  83. #include "data.h"
  84. #include "buffer.h"
  85. #include "iface.h"
  86. #include "timer.h"
  87. #include "ax25.h"
  88. #include "ax25l2.h"
  89. #include "l3struc.h"
  90. #include "x25cause.h"
  91. #include "l3calls.h"
  92. #include "tx.h"
  93. #include "config.h"
  94. #include "upfcn.h"
  95.  
  96. int NULLFCN(), clr_heard(), con_heard(), recv_boot();
  97. int send_heard(), rst_boot(), init_heard(), unload_heard();
  98.  
  99. struct upfcn heard={
  100.     {{0x90, 0x8a, 0x82, 0xa4, 0x88, 0x40}, {0x00}}, /* HEARD-0 */
  101.     rst_boot, clr_heard, con_heard, recv_boot,
  102.     send_heard, init_heard, unload_heard,
  103.     "HEARD  - ROSE Switch MHeard List, Version 1.0\r"
  104. };
  105.  
  106. struct VCS *heard_llcn;
  107. struct datastr *mkpkt(), *bappstr();
  108. struct datastr *heard_in;
  109. struct tmrblk *heard_timer;
  110. void siosnd();
  111. struct datastr *ax25l2(), *heardit();
  112. int NULLFCN();
  113. struct datastr *NULLPKT();
  114.  
  115. int callcmp();
  116.  
  117. extern unsigned char digi;
  118.  
  119. extern struct axcb *links;
  120. extern struct interface *ifaces[4];
  121. extern struct interface port0, port1;
  122.  
  123. extern unsigned char node_addr[16];
  124.  
  125. struct interface Port0 = {0, "Port 0", siosnd, heardit, NULLPKT, NULLFCN, NULLFCN };
  126. struct interface Port1 = {1, "Port 1", siosnd, heardit, NULLPKT, NULLFCN, NULLFCN };
  127.  
  128. char *ftype_name[] = {  "      ","   I  ","  RR  ","  RNR ","  REJ ","  UI  ",
  129.             " DISC ","  UA  "," FRMR ","  DM  "," SABM " };
  130.  
  131. struct mhlist {
  132.     unsigned int age;    /* How long ago we "first" heard this entry */
  133.     unsigned int last;    /* How long ago we last heard this entry */
  134.     int port;        /* Port they were heard on */
  135.     unsigned int rxc;    /* How many frames have been heard */
  136.     char *ftype;        /* Frame type of last frame */
  137.      struct ax25_addr call[7];
  138. };
  139.  
  140. #define LISTSIZE 32
  141.  
  142. struct mhlist heard_list[LISTSIZE];
  143.  
  144. zap_it(mhl)
  145. register struct mhlist *mhl;
  146. {
  147.     static int i,j;
  148.  
  149.     mhl->age =
  150.     mhl->last =
  151.     mhl->port =
  152.     mhl->rxc = 0;
  153.     mhl->ftype = ftype_name[0];
  154.     for (i=0;i<7;i++) {
  155.         for (j=0;j<ALEN;j++) mhl->call[i].call[j] = 0;
  156.         mhl->call[i].ssid = 0;
  157.     }
  158. }
  159.  
  160. int
  161. heard_tick()
  162. {
  163.     static int i, j;
  164.     register struct mhlist *mhl;
  165.  
  166.     queue(&heard_timer, heard_tick, 5, 0);
  167.  
  168.     mhl = &heard_list[0];
  169.     for (i=0;i<LISTSIZE;i++) /* Make each entry get older */ {
  170.         if (mhl->call[0].call[0] == 0) break;
  171.         mhl->age++;
  172.         mhl->last++;
  173.         mhl++;
  174.     }
  175. }
  176.  
  177. int
  178. init_heard()
  179. {
  180.     static int i;
  181.     static struct axcb *axcb;
  182.     register struct mhlist *mhl;
  183.  
  184.     mhl = heard_list;
  185.     for (i=0;i<LISTSIZE;i++) zap_it(mhl++);
  186.  
  187.     queue(&heard_timer, heard_tick, 5, 0);
  188.     heard_llcn = NULL;
  189.  
  190.     axcb = links;
  191.     while (axcb) /* Fix all iface's of all links */ {
  192.         if (axcb->iface == ifaces[0]) axcb->iface = &Port0;
  193.         if (axcb->iface == ifaces[1]) axcb->iface = &Port1;
  194.         axcb=axcb->next;
  195.     }
  196.     ifaces[0] = &Port0;
  197.     ifaces[1] = &Port1;
  198. }
  199.  
  200. int
  201. unload_heard()
  202. {
  203.     static struct VCS *vc;
  204.     register struct axcb *axcb;
  205.  
  206.     ifaces[0] = &port0;
  207.     ifaces[1] = &port1;
  208.  
  209.     kill(heard_timer);
  210.     while (heard_llcn) /* Clear all active calls */ {
  211.         vc = heard_llcn;
  212.         heard_llcn = vc->next;
  213.         set_p(vc, P6, DTE_Orig+122);
  214.     }
  215.     axcb = links;
  216.     while (axcb) /* Restore any links to the correct interface */ {
  217.         if (axcb->iface == &Port0) axcb->iface = &port0;
  218.         if (axcb->iface == &Port1) axcb->iface = &port1;
  219.         axcb = axcb->next;
  220.     }
  221.     return 1;
  222. }
  223.  
  224. int
  225. con_heard(vc)
  226. register struct VCS *vc;
  227. {
  228.     vc->next = heard_llcn;    /* This works even when _llcn is NULL */
  229.     heard_llcn = vc;
  230.  
  231.     vc=vc->peer;
  232.     if (!vc) return;
  233.     (*vc->SEND)(vc,info_pkt());
  234. }
  235.  
  236. int
  237. clr_heard(vc,c)
  238. struct VCS *vc;
  239. int c;
  240. {
  241.     register struct VCS *vcp;
  242.  
  243.     if (heard_llcn == vc) heard_llcn = vc->next; /* First item */
  244.     else {
  245.         vcp = heard_llcn;
  246.         while (vcp->next && vcp->next != vc) vcp = vcp->next;
  247.         if (vcp->next == vc) vcp->next = vc->next;
  248.     }
  249.     vc->next = NULL;
  250.     set_p(vc, P1, 0);
  251. }
  252.  
  253. int
  254. send_heard(vc, pkt)
  255. struct VCS *vc;
  256. struct datastr *pkt;
  257. {
  258.     static int i;
  259.  
  260.     vc_queue_data(vc,pkt);
  261.     i = 20;        /* Default to One Screen Full */
  262.     if (vc->tx_queue) /* There is stuff waiting */ {
  263.         while ((heard_in = vc->tx_queue)) {
  264.             vc->tx_queue = heard_in->next;
  265.             if (bgetch(&heard_in) == '*') i = LISTSIZE; /* ALL */
  266.             free_buffer(heard_in);
  267.         }
  268.         heard_stns(vc->peer, i);
  269.     }
  270.     return 256;    /* We are never busy! */
  271. }
  272.  
  273. int
  274. find_guy(mh)
  275. struct ax25_addr mh[7];
  276. {
  277.     static int i, j, c;
  278.  
  279.     for (i=0;i<7;i++) /* Check each address */ {
  280.         for (j=0;j<ALEN;j++) {
  281.             c = mh[i].call[j] & 0x0ff;
  282.             if (c != 0 && c < 0x40) return -2;
  283.         }
  284.     }
  285.     for (i=0;i<LISTSIZE;i++) /* See if we have heard this guy before */ {
  286.         for (j=0;j<7;j++) /* Still have a match? */ {
  287.             if (!callcmp(&mh[j], &heard_list[i].call[j])) break;
  288.             if (j == 6) return i;    /* All Matches! */
  289.         }
  290.     }
  291.     return -1;
  292. }
  293.  
  294. struct datastr *
  295. heardit(iface, pkt)
  296. struct interface *iface;
  297. struct datastr *pkt;
  298. {
  299.     static struct datastr *bp;
  300.     static int i, j, k, l, xmtr;
  301.     static struct ax25_addr mh[7];
  302.     int get_addr();
  303.  
  304.     bp = dup_pkt(pkt);
  305.     for (i=0;i<7;i++) /* Init calls */ {
  306.         for (j=0;j<ALEN;j++) mh[i].call[j] = 0;
  307.         mh[i].ssid = 0;
  308.     }
  309.     if ((xmtr=get_addr(bp, mh, TRUE)) > 1) /* Had valid addresses */ {
  310.         if (xmtr > 2) /* Have digipeaters */ {
  311.             if (digi > 2) {
  312.                 xmtr = digi;
  313.             } else if (digi) xmtr=0;
  314.         }
  315.         i = find_guy(mh);
  316.         if (i != -2) {
  317.             j = k = 0;
  318.             if (i == -1) i = LISTSIZE-1;
  319.             else {
  320.                 j = heard_list[i].age;
  321.                 k = heard_list[i].rxc;
  322.             }
  323.             if (i) for (l=i;l>0;l--) {
  324.                 bmove(&heard_list[l-1],&heard_list[l], sizeof(struct mhlist));
  325.             }
  326.             heard_list[0].port = iface->dev;
  327.             heard_list[0].age = j;
  328.             heard_list[0].last = 0;
  329.             heard_list[0].rxc = k+1;
  330.             for (i=0;i<7;i++) {
  331.                 mh[i].ssid &= SSID;
  332.                 callcpy(&heard_list[0].call[i], &mh[i]);
  333.             }
  334.             /* digi points to the NEXT digi, not the XMTR! */
  335.             if (xmtr>2) heard_list[0].call[xmtr-1].ssid |= REPEATED;
  336.             if (bp) heard_list[0].ftype =
  337.                     ftype_name[decode_ctl(*bp->rdata)+1];
  338.         }
  339.     }
  340.     free_pkt(bp);
  341.     return (ax25l2(iface, pkt));
  342. }
  343.  
  344. int call_strx(stn, str)
  345. unsigned char *stn, *str;
  346. {
  347.     static int i;
  348.     int call_str();
  349.  
  350.     i = call_str(stn, str);
  351.     if (str[i-1] == '0' && str[i-2] == '-') i -= 2;
  352.     return i;
  353. }
  354.  
  355. heard_stns(vc, num)
  356. struct VCS *vc;
  357. int num;
  358. {
  359.     static struct datastr *bp;
  360.     static int i, j;
  361.     static char str[80], *ch;
  362.     register struct mhlist *mhl;
  363.     int x121_str();
  364.  
  365.     bp=mkpkt("Heard List for ");
  366.     ch = str;
  367.     ch += call_strx(&L3CALL[0], ch);
  368.     *ch++ = ' ';
  369.     *ch++ = ' ';
  370.     ch += x121_str(node_addr, ch);
  371.     *ch++ = 0x0d;
  372.     *ch++ = 0x0d;
  373.     *ch = 0;
  374.     bappstr(bp, str);
  375.  
  376.     mhl = heard_list;
  377.     for (i=0;i<num;i++) /* For each item in the list */ {
  378.         if (mhl->call[0].call[0] == 0) break;
  379.         ch = str;
  380.         *ch++ = ' ';
  381.         *ch++ = mhl->port+0x30;
  382.         *ch++ = ' ';
  383.         ch += call_strx(&mhl->call[1], ch);
  384.         *ch++ = '>';
  385.         ch += call_strx(&mhl->call[0], ch);
  386.         *ch = 0;
  387.         bappstr(bp,str);
  388.  
  389.         ch = str;
  390.         *ch = ',';
  391.         for (j=2;j<7;j++) /* Do the Path */ {
  392.             if (mhl->call[j].call[0] == 0) break;
  393.             ch++;
  394.             ch += call_strx(&mhl->call[j], ch);
  395.             if (mhl->call[j].ssid & REPEATED) *ch++ = '*';
  396.             *ch = ',';
  397.         }
  398.         *ch++ = 0x0d;
  399.         *ch = 0;
  400.         bappstr(bp, str);
  401.         mhl++;
  402.     }
  403.     bappstr(bp, "END>\r");
  404.     (*vc->SEND)(vc, bp);
  405. }
  406.